package com.niiwoo.civet.mobile.util;

import com.niiwoo.civet.user.constants.LoginAccountErrorCode;
import com.niiwoo.tripod.provider.exception.BizException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 校验
 */
public class ParameterValidator {

    public static final Logger logger = LoggerFactory.getLogger(ParameterValidator.class);

    private static final Pattern VALID_CHAR = Pattern.compile("^[a-zA-Z0-9\\-/:\\);\\($&@\"\\.,?'!\\[\\]{}#%^*\\+=_\\\\|~<>￥€£●¥·•]{6,16}$");

    private static final Pattern NUMBERS = Pattern.compile("[0-9]+");

    private static final Pattern LETTERS = Pattern.compile("[a-zA-Z]+");

    private static final Pattern SPECIAL_CHAR = Pattern.compile("[\\-/:\\);\\($&@\"\\.,?'!\\[\\]{}#%^*\\+=_\\\\|~<>￥€£●¥•·]+");

    private static final Pattern MOBILE_PATTERN = Pattern.compile("^1[3456789][0-9]{9}$");

    private static final Pattern CHINESE_NAME_PATTERN = Pattern.compile("^[\\u3400-\\u4DB5\\u4E00-\\u9FA5\\u9FA6-\\u9FBB\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFF00-\\uFFEF\\u2E80-\\u2EFF\\u3000-\\u303F\\u31C0-\\u31EF·]{2,15}$");

    /**
     * 验证登录密码， 数字、字符和特殊字符至少存在其中两种
     *
     * @PARAM PASSOWRD 登录密码
     */
    public static boolean valid(String password) {
        return Optional.ofNullable(password)
                .map(p -> {
                    boolean isMatchValidChar = isValidChar(p);
                    if (!isMatchValidChar) return false;
                    boolean isMatchNumber = isMatchNumber(p);
                    boolean isMatchLetter = isMatchLetter(p);
                    if (isMatchNumber && isMatchLetter) return true;
                    boolean isMatchSpecialChar = isMatchSpecialChar(p);
                    if (isMatchNumber && isMatchSpecialChar) return true;
                    if (isMatchLetter && isMatchSpecialChar) return true;
                    return false;
                })
                .orElse(false);
    }

    public static boolean isValidChar(String password) {
        return isMatch(VALID_CHAR, password);
    }

    public static boolean isMatchNumber(String password) {
        return isMatch(NUMBERS, password);
    }

    public static boolean isMatchLetter(String password) {
        return isMatch(LETTERS, password);
    }

    public static boolean isMatchSpecialChar(String password) {
        return isMatch(SPECIAL_CHAR, password);
    }

    public static boolean isMatch(Pattern pattern, String str) {
        return Optional.ofNullable(str).map(s -> pattern.matcher(str).find()).orElse(false);
    }

    public static boolean isMobileNo(String mobileNo) {
        return isMatch(MOBILE_PATTERN, mobileNo);
    }

    public static boolean isChineseName(String name) {
        if (isMatch(CHINESE_NAME_PATTERN, name)) {
            int dotIndex = name.indexOf("·");
            if (dotIndex == -1 && name.length() > 8) {
                return false;
            }
            if (dotIndex == 1 || dotIndex == name.length() - 1) {
                return false;
            }
            return true;
        }
        return false;
    }


    public static String toTuanDaiPassword(String password) {
        return Optional.ofNullable(password)
                .map(p -> {
                    try {
                        // 1. 拼接
                        byte[] ps = String.format("tuan%sdai", p).getBytes("utf-8");
                        // 2. 一次 sha-1 & Hex & upper case
                        String sha1Pwd = new String(Hex.encodeHex(DigestUtils.getSha1Digest().digest(ps))).toUpperCase();
                        byte[] sha1PwdBytes = sha1Pwd.getBytes("utf-8");
                        // 2. 再一次 md5 & Hex & upper case
                        return new String(Hex.encodeHex(DigestUtils.getMd5Digest().digest(sha1PwdBytes))).toUpperCase();
                    } catch (Exception e) {
                        logger.error(String.format("密码转换成团贷哈希值错误, password=%s, errorMessage=%s", p, e.getMessage()), e);
                        throw new BizException(LoginAccountErrorCode.PASSWORD_FORMAT_ERROR);
                    }
                })
                .orElseThrow(() -> new BizException(LoginAccountErrorCode.PASSWORD_FORMAT_ERROR));
    }

    /**
     * 返回多少字节长度
     * @param str
     * @param n
     * @return
     */
    public static int trimGBK(String str,int n) {
        int num = 0;
        try {
            byte[] buf = str.getBytes("GBK");
            boolean bChineseFirstHalf = false;
            for(int i=0; i<n && i< buf.length; i++){
                if(buf[i]<0 && !bChineseFirstHalf){ //是中文的情况,num不用++
                    bChineseFirstHalf = true;
                }else{
                    num++;
                    bChineseFirstHalf = false;
                }
            }
        }catch (UnsupportedEncodingException ex){
        }
        return num;
    }

    public static String emojiConvert(String str) {
        String returnStr = "";
        try {
            String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
            Pattern pattern = Pattern.compile(patternString);
            Matcher matcher = pattern.matcher(str);
            StringBuffer sb = new StringBuffer();
            while (matcher.find()) {
                try {
//                  matcher.appendReplacement(sb, "[[" + URLEncoder.encode(matcher.group(1), "UTF-8") + "]]");
                    matcher.appendReplacement(sb, "*");
                } catch (Exception e) {
                }
            }
            matcher.appendTail(sb);
            returnStr = sb.toString();
        }catch (Exception e){}
        return returnStr;
    }

     /*
    public static String toTuanDaiPassword2(String password) {
        // 加密码
        StringBuffer str = new StringBuffer();
        str.append("tuan").append(password).append("dai");
        String results = null;
        MessageDigest mDigest;
        try {
            mDigest = MessageDigest.getInstance("SHA1");
            byte[] result = mDigest.digest(str.toString().getBytes());
            String sha1_input = byteToStringHex(result);// sb.toString().toUpperCase();
            mDigest = MessageDigest.getInstance("MD5");
            String md5input = sha1_input.toUpperCase();
            mDigest.update(md5input.getBytes());
            result = mDigest.digest();
            results = byteToStringHex(result);// buf.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return results;

    }

    public static String byteToStringHex(byte[] result) {
        StringBuffer sb = new StringBuffer();
        for (byte element : result) {
            sb.append(Integer.toString((element & 0xff) + 0x100, 16)
                    .substring(1));
        }
        return sb.toString().toUpperCase();
    }
    */

    /**
     * 格式化成****亿****万
     */
    public static String getYiWan(String money) {
        String result = "";
        long value = BigDecimal.valueOf(Double.valueOf(money) / 10000).setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
        if(0 >= value){
            return money + "";
        }
        int yi = (int)(value / 10000);
        int wan = (int)(value - yi * 10000L);
        if(yi < 1) {
            result = wan + "万";
        }else {
            result = yi + "亿" + wan + "万";
        }
        return result;
    }

}
